package com.wxsm.wechat.util;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * 一个校验码生成器的类，其功能主要包括两部分(得到渲染图片和校验码字符串)
 * 同时可以设置图片中字符的字体大小及字符的个数(图片的大小会根据所设置的相关参数而自适应)
 */
public class CaptchaGenerator {

    //默认字符的字体大小
    private int charSize = 24;
    //默认产生字符的数量
    private int charsAmount = 4;
    private int lineCount = 100;
    private String fontName = "Arial Black";
    private int imageWidth;
    private int imageHeight;

    private BufferedImage bufferedImage;
    private String captcha;

    private static final Random random = new Random();

    public CaptchaGenerator() {

    }

    public CaptchaGenerator(int charSize, int charsAmount) {
        setCharSize(charSize);
        setCharsAmount(charsAmount);
    }

    public void createImage() {
        Font font = new Font(fontName, Font.PLAIN, charSize);
        imageWidth = charsAmount * (int) (charSize * 0.9);
        imageHeight = (int) (Math.ceil(charSize / 0.8));
        bufferedImage = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
        Graphics graphics = bufferedImage.getGraphics();
        // 将图形上下文(填充区域)的当前颜色设置为指定颜色
        graphics.setColor(getRandomColor(200, 250));
        // 设置填充区域
        graphics.fillRect(0, 0, imageWidth - 1, imageHeight - 1);
        // 将图形上下文(绘画区域边框)的当前颜色设置为指定颜色
        graphics.setColor(new Color(102, 102, 102));
        // 设置绘画区域边框
        graphics.drawRect(0, 0, imageWidth - 1, imageHeight - 1);
        // 设置字体
        graphics.setFont(font);
        // 将图形上下文(区域内线条)的当前颜色设置为指定颜色
        graphics.setColor(getRandomColor(160, 200));
        // 随机画线
        this.drawLine(graphics);
        // 填充验证码
        this.setCaptcha(graphics);
        graphics.dispose();
    }

    public BufferedImage getImage() {
        return bufferedImage;
    }

    public String getCaptcha() {
        return captcha;
    }

    private void drawLine(Graphics graphics) {
        for (int i = 0; i < lineCount; i++) {
            //为图像画线条
            int x = random.nextInt(imageWidth - 1);
            int y = random.nextInt(imageHeight - 1);
            int xl, yl;
            if (i % 2 == 0) {
                xl = random.nextInt(6) + 1;
                yl = random.nextInt(12) + 1;
            } else {
                xl = -(random.nextInt(12) + 1);
                yl = -(random.nextInt(6) + 1);
            }
            graphics.drawLine(x, y, x + xl, y + yl);
        }
    }

    private void setCaptcha(Graphics graphics) {
        int unitCharPixel = (imageWidth - charsAmount) / charsAmount;
        int unitHeight = (imageHeight - charSize) / 2 + charSize - 2;
        StringBuffer sbCaptcha = new StringBuffer();
        for (int i = 0; i < charsAmount; i++) {
            String sChar = RandomStrUtil.getOneRandomStringCode();
            sbCaptcha.append(sChar);
            //为每一个字符设置独立的前景色
            graphics.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
            graphics.drawString(sChar, unitCharPixel * i + charsAmount / 2, unitHeight);
        }
        captcha = sbCaptcha.toString();
    }

    private Color getRandomColor(int foregroundColor, int backgroundColor) {
        Random random = new Random();
        if (foregroundColor > 255) {
            foregroundColor = 255;
        }
        if (backgroundColor > 255) {
            backgroundColor = 255;
        }
        int red = foregroundColor + random.nextInt(backgroundColor - foregroundColor);
        int green = foregroundColor + random.nextInt(backgroundColor - foregroundColor);
        int blue = foregroundColor + random.nextInt(backgroundColor - foregroundColor);
        return new Color(red, green, blue);
    }

    public void setCharSize(int charSize) {
        if (charSize < 20) {
            charSize = 20;
        }
        this.charSize = charSize;
    }

    public void setCharsAmount(int charsAmount) {
        if (charSize < 3) {
            charSize = 3;
        }
        this.charsAmount = charsAmount;
    }

    public void setFontName(String fontName) {
        this.fontName = fontName;
    }

    public void setLineCount(int lineCount) {
        this.lineCount = lineCount;
    }

//    public static void main(String[] args) {
//        CaptchaGenerator captchaGenerator = new CaptchaGenerator();
//        captchaGenerator.createImage();
//        System.out.println(captchaGenerator.getCaptcha());
//        ByteArrayOutputStream output = new ByteArrayOutputStream();
//        ByteArrayInputStream input = null;
//        try {
//            ImageOutputStream imageOut = ImageIO.createImageOutputStream(output);
//            ImageIO.write(captchaGenerator.getImage(), "JPEG", imageOut);//将图像按JPEG格式写入到imageOut中，即存入到output的字节流中
//            imageOut.close();//关闭写入流
//            input = new ByteArrayInputStream(output.toByteArray());//input读取output中的图像信息
//        } catch (Exception e) {
//            System.out.println("验证码图片产生出现错误：" + e.toString());
//        }
//    }
}